package com.yunji.cabinet.task;

import com.google.common.collect.Lists;
import com.yunji.cabinet.bo.UpgradeInfoListBO;
import com.yunji.cabinet.bo.UpgradeTaskListBO;
import com.yunji.cabinet.domain.UpgradeInfoDO;
import com.yunji.cabinet.domain.UpgradeTaskDO;
import com.yunji.cabinet.engine.UpgradeTaskEngine;
import com.yunji.cabinet.enums.UpgradeTaskStatus;
import com.yunji.cabinet.service.IUpgradeInfoService;
import com.yunji.cabinet.service.IUpgradeTaskService;
import com.yunji.common.constant.LogicCode;
import com.yunji.common.utils.ConvertDataUtil;
import com.yunji.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component("upgradeTask")
public class UpgradeTask {

    @Resource
    private IUpgradeTaskService upgradeTaskService;

    @Resource
    private IUpgradeInfoService upgradeInfoService;

    @Resource
    private UpgradeTaskEngine upgradeTaskEngine;

    @Transactional
    public void reset() {
        // 定时拉取需要重试的任务 无法用等待中判断
        // 根据任务创建时间进行分组 从创建时间最新的进行任务重试
        // 重试一样需要加锁 判断是否是最新执行任务
        List<UpgradeTaskDO> taskList = upgradeTaskService.search(UpgradeTaskListBO.builder().taskStatus(UpgradeTaskStatus.IN_PROGRESS.getCode()).build());
        List<String> codeList = ConvertDataUtil.list2FieldList(taskList, UpgradeTaskDO::getTaskCode);

        Map<UpgradeTaskDO,List<UpgradeInfoDO>> map = new HashMap<>();
        for (UpgradeTaskDO task : taskList) {
            UpgradeInfoListBO infoListBO = new UpgradeInfoListBO();
            infoListBO.setTaskCode(task.getTaskCode());
            infoListBO.setWhetherRetry(LogicCode.YES);
            List<UpgradeInfoDO> infoDOList = upgradeInfoService.getUpgradeInfoList(infoListBO);
            if (BeanUtils.isNotNull(infoDOList)){
                map.put(task, infoDOList);
            }else {
                // 若是没有找到需要执行的任务 则说明任务已完成
                upgradeTaskService.modifyStatus(task.getTaskCode(),UpgradeTaskStatus.BE_FINISHED.getCode(), Lists.newArrayList(UpgradeTaskStatus.IN_PROGRESS.getCode()));
            }
        }

        for (Map.Entry<UpgradeTaskDO, List<UpgradeInfoDO>> entry : map.entrySet()) {

            upgradeTaskEngine.retryTask(entry.getKey(),entry.getValue());
        }
    }

}
